package sword

import (
	"crypto/md5"
	"crypto/sha1"
	"encoding/hex"
	"fmt"
	"github.com/astaxie/beego"
	"math"
	"math/rand"
	"net/url"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"time"
	"unicode/utf8"
)

//MD5加密64位
func ToMD5(old string) (neww string) {
	md5pwd := md5.New()
	md5pwd.Write([]byte(old))
	password := md5pwd.Sum(nil)
	neww = hex.EncodeToString(password)
	return
}

//时间
func Gettimes(format string) (timeres string) {
	timestemp := time.Now().Unix()
	tm := time.Unix(timestemp, 10)
	if format == "" {
		format = `2006-01-02 15:04:05`
	}
	return tm.Format(format)
}

//时间戳
func Gettimestemp() (timestemp int64) {
	timestemp = time.Now().Unix()
	return
}
func Gettimestemps() (timestemps string) {
	timestemp := time.Now().Unix()
	timestemps = strconv.FormatInt(timestemp, 10)
	return
}

func Timestringtoint64(timestring string) (timeint int64) {
	var times time.Time
	var err error
	if len(timestring) == 19 {
		times, err = time.Parse("2006-01-02 15:04:05", timestring)
	} else if len(timestring) == 16 {
		times, err = time.Parse("2006-01-02 15:04", timestring)
	} else {
		times, err = time.Parse("2006-01-02", timestring)
	}
	if err != nil {
		beego.Debug("时间字符砖转换时间戳失败:", err)
	}
	return times.Unix()
}

// 过滤 emoji 表情
func FilterEmoji(content string) string {
	var new_content string
	for _, value := range content {
		_, size := utf8.DecodeRuneInString(string(value))
		if size <= 3 {
			new_content += string(value)
		}
	}
	return new_content
}

//分页
func Paginator(page, prepage int, nums int64) map[string]interface{} {

	var firstpage int //第一页地址
	var lastpage int  //最后一页地址
	var nextpage int  //后一页地址
	var prevpage int  //前一页地址
	//根据nums总数，和prepage每页数量 生成分页总数
	totalpages := int(math.Ceil(float64(nums) / float64(prepage))) //page总数
	if page > totalpages {
		page = totalpages
	}
	if page <= 0 {
		page = 1
	}
	var pages []int
	switch {
	case page > totalpages-5 && totalpages > 5: //最后5页
		start := totalpages - 5 + 1
		prevpage = page - 1
		firstpage = 1
		lastpage = totalpages
		nextpage = int(math.Min(float64(totalpages), float64(page+1)))
		pages = make([]int, 5)
		for i, _ := range pages {
			pages[i] = start + i
		}
	case page >= 3 && totalpages > 5:
		start := page - 3 + 1
		pages = make([]int, 5)
		prevpage = page - 3
		firstpage = 1
		lastpage = totalpages
		for i, _ := range pages {
			pages[i] = start + i
		}
		prevpage = page - 1
		nextpage = page + 1
	default:
		pages = make([]int, int(math.Min(5, float64(totalpages))))
		for i, _ := range pages {
			pages[i] = i + 1
		}
		firstpage = 1
		lastpage = totalpages
		prevpage = int(math.Max(float64(1), float64(page-1)))
		nextpage = page + 1
		//fMt.Println(pages)
	}
	paginatorMap := make(map[string]interface{})
	paginatorMap["pages"] = pages           //页数
	paginatorMap["totalpages"] = totalpages //总页数
	paginatorMap["firstpage"] = firstpage   //首页
	paginatorMap["lastpage"] = lastpage     //末页
	paginatorMap["prevpage"] = prevpage     //上一页
	paginatorMap["nextpage"] = nextpage     //下一页
	paginatorMap["currpage"] = page
	return paginatorMap
}

func UeditorImg(ue string) []string {
	str := `(?is)<img.*?>`
	str2 := `(src|SRC)=(\"|\')(.*?)(\"|\')`
	res2 := regexp.MustCompile(str).FindAllString(ue, -1)
	var res []string
	for _, v := range res2 {
		q := regexp.MustCompile(str2).FindString(v)
		q2 := strings.Split(q, `"`)
		if q2[1] != `https://101.37.147.74/static/ueditor/themes/default/images/spacer.gif ` && q2[1] != `https://www.haotuis.com/static/ueditor/themes/default/images/spacer.gif` {
			res = append(res, q2[1])
		}
	}
	return res
}

//RandomStr 随机生成字符串
func RandStr(length int) string {
	str := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
	bytes := []byte(str)
	result := []byte{}
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i := 0; i < length; i++ {
		result = append(result, bytes[r.Intn(len(bytes))])
	}
	return string(result)
}

func sha1s(s string) string {
	r := sha1.Sum([]byte(s))
	return hex.EncodeToString(r[:])
}

func UeditorChange(url, ue string) (uec string) {
	style := `style="width:100% !important;height:auto; vertical-align:bottom; display:block;" `
	// uec = strings.Replace(ue, `style`, `stylenone`, -1)
	// uec = strings.Replace(uec, `style="float:none;"`, "", -1)
	// uec = strings.Replace(uec, `style="float:none"`, "", -1)
	// uec = strings.Replace(uec, `style="float: none"`, "", -1)
	uec = strings.Replace(ue, `src="`, style+`src="`, -1)
	uec = strings.Replace(uec, `<p>`, `<p style="line-height:22px;font-size:14px;padding:3px 0">`, -1)
	return
}

// 分页
func Pagechange(now string, num string) (page string, page2 int, nums string) {
	if now == "" {
		now = "1"
	}
	if num == "" {
		num = "10"
	}
	page2, _ = strconv.Atoi(now)
	numint, _ := strconv.Atoi(num)
	pages := (page2 - 1) * numint
	nums = num
	page = strconv.Itoa(pages)
	return
}

func Timetran(t string) time.Time {
	var layout string
	lent := len(t)
	if lent == 19 {
		layout = "2006-01-02 15:04:05"
	} else if lent == 16 {
		layout = "2006-01-02 15:04"
	} else {
		layout = "2006-01-02"
	}
	loc, _ := time.LoadLocation("Local")
	timeasia, _ := time.ParseInLocation(layout, t, loc)
	return timeasia
}
func Timeget() time.Time {
	return time.Now().Local()
}
func RandomStr(length int) string {
	str := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
	bytes := []byte(str)
	result := []byte{}
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i := 0; i < length; i++ {
		result = append(result, bytes[r.Intn(len(bytes))])
	}
	return string(result)
}
func wxpayCalcSign(mReq map[string]interface{}, key string) string {

	//fmt.Println("========STEP 1, 对key进行升序排序.========")
	//fmt.Println("微信支付签名计算, API KEY:", key)
	//STEP 1, 对key进行升序排序.
	sorted_keys := make([]string, 0)
	for k, _ := range mReq {
		sorted_keys = append(sorted_keys, k)
	}
	sort.Strings(sorted_keys)
	//fmt.Println("========STEP2, 对key=value的键值对用&连接起来，略过空值========")
	//STEP2, 对key=value的键值对用&连接起来，略过空值
	var signStrings string
	for _, k := range sorted_keys {
		//fmt.Printf("k=%v, v=%v\n", k, mReq[k])
		value := fmt.Sprintf("%v", mReq[k])
		if value != "" {

			signStrings += k + "=" + url.QueryEscape(value) + "&"
		}
	}
	//fmt.Println("========STEP3, 在键值对的最后加上key=API_KEY========")
	//STEP3, 在键值对的最后加上key=API_KEY
	if key != "" {
		signStrings = signStrings + "app_key=" + key
	}
	//fmt.Println("========STEP4, 进行MD5签名并且将所有字符转为大写.========")
	//STEP4, 进行MD5签名并且将所有字符转为大写.
	md5Ctx := md5.New()
	md5Ctx.Write([]byte(signStrings))
	cipherStr := md5Ctx.Sum(nil)
	upperSign := strings.ToUpper(hex.EncodeToString(cipherStr))
	return upperSign
}
func CkeditorChange(s string) string {
	s = strings.Replace(s, "&ldquo;", `"`, -1)
	s = strings.Replace(s, "&lsquo;", `'`, -1)
	s = strings.Replace(s, "&rdquo;", `"`, -1)
	s = strings.Replace(s, "&rsquo;", `'`, -1)
	s = strings.Replace(s, "&hellip;", `...`, -1)
	s = strings.Replace(s, "&quot;", `"`, -1)
	s = strings.Replace(s, "&mdash;", `—`, -1)
	return s
}

func Sum(a, b string) string {
	ai, _ := strconv.ParseFloat(a, 64)
	bi, _ := strconv.ParseFloat(b, 64)
	return AddOne(ai + bi)
}

func Cut(a, b string) string {
	ai, _ := strconv.ParseFloat(a, 64)
	bi, _ := strconv.ParseFloat(b, 64)
	return AddOne(ai - bi)
}

func Mult(a, b string) string {
	ai, _ := strconv.ParseFloat(a, 64)
	bi, _ := strconv.ParseFloat(b, 64)
	return AddOne(ai * bi)
}

func Divi(a, b string) string {
	ai, _ := strconv.ParseFloat(a, 64)
	bi, _ := strconv.ParseFloat(b, 64)
	return AddOne(ai / bi)
}

func AddOne(res float64) string {
	ress := fmt.Sprintf(`%.3f`, res)
	resslice := strings.Split(ress, ".")
	resf := resslice[0]
	resl := resslice[1]
	var returnres string
	resli, _ := strconv.Atoi(resl)
	bai := resli / 100
	shi := (resli - bai*100) / 10
	ge := resli - bai*100 - shi*10
	if ge == 0 {
		returnres = fmt.Sprintf(`%v.%v%v`, resf, bai, shi)
	} else {
		resfi, _ := strconv.Atoi(resf)
		shi += 1
		if shi == 10 {
			shi = 0
			bai += 1
			if bai == 10 {
				bai = 0
				resfi += 1
			}
		}
		returnres = fmt.Sprintf(`%v.%v%v`, resfi, bai, shi)
	}
	return returnres
}

// type AliyunSmsCode struct {
// 	Code string `json:"code"`
// }
// type AliyunSmsRe struct {
// 	RequestId string `json:"RequestId"`
// 	Code      string `json:"Code"`
// 	Message   string `json:"Message"`
// 	BizId     string `json:"BizId"`
// }

// func AliyunSendSms(appid,secret,mobile, sign, tcode string) (string, error) {
// 	var code AliyunSmsCode
// 	code.Code = RandomNum(6)
// 	codejson, err := json.Marshal(code)
// 	if err != nil {
// 		return code.Code, err
// 	} else {
// 		var parms = make(map[string]interface{})
// 		parms["SignatureMethod"] = "HMAC-SHA1"
// 		parms["SignatureNonce"] = RandomStr(32)
// 		parms["AccessKeyId"] = appid
// 		parms["SignatureVersion"] = "1.0"
// 		parms["Timestamp"] = Gettimes("2006-01-02'Monday'15:04:05'GMT'")

// 		parms["Action"] = "SendSms"
// 		parms["Version"] = "2017-05-25"
// 		parms["RegionId"] = "cn-hangzhou"
// 		parms["PhoneNumbers"] = mobile
// 		parms["SignName"] = sign
// 		parms["TemplateParam"] = string(codejson)
// 		parms["TemplateCode"] = tcode

// 		parms["sign"]=AliyunSmsSort(parms)

// 		r, err := req.Bytes()
// 		beego.Debug(string(r))
// 		beego.Debug(err)
// 		var res AliyunSmsRe
// 		if err = req.ToJSON(&res); err != nil {
// 			beego.Debug(err)
// 			return code.Code, err
// 		} else {
// 			beego.Debug(res)
// 			if res.Code == "ok" {
// 				beego.Debug(err)
// 				return code.Code, err
// 			} else {
// 				err = errors.New(res.Message)
// 				beego.Debug(err)
// 				return code.Code, err
// 			}
// 		}
// 	}
// 	return code.Code, err
// }

func RandomNum(length int) string {
	str := "0123456789"
	bytes := []byte(str)
	result := []byte{}
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i := 0; i < length; i++ {
		result = append(result, bytes[r.Intn(len(bytes))])
	}
	return string(result)
}

// func SpecialUrlEncode(key string) string {
// 	key=url.ParseQuery(key)
// 	key=strings.Replace(key, "+", "%20", -1)
// 	key=strings.Replace(key, "*", "%2A", -1)
// 	key=strings.Replace(key, "%7E", "~", -1)
// 	return key
// }

// func AliyunSmsSort(params map[string]interface,secret string) string {
// 	sorted_keys := make([]string, 0)
// 	for k, _ := range params {
// 		sorted_keys = append(sorted_keys, k)
// 	}
// 	sort.Strings(sorted_keys)
// 	var signStrings string
// 	for _, k := range sorted_keys {
// 		//fmt.Printf("k=%v, v=%v\n", k, mReq[k])
// 		value := fmt.Sprintf("%v", params[k])
// 		if value != "" {
// 			signStrings = signStrings + SpecialUrlEncode(k) + "=" + SpecialUrlEncode(value) + "&"
// 		}
// 	}
// 	signStrings=strings.Trim(signStrings, "&")
// 	signStrings=secret+"&POST&"+SpecialUrlEncode("/")+"&"+specialUrlEncode(signStrings)
// 	md5Ctx := md5.New()
// 	md5Ctx.Write([]byte(signStrings))
// 	cipherStr := md5Ctx.Sum(nil)
// 	upperSign := strings.ToUpper(hex.EncodeToString(cipherStr))
// 	return upperSign
// }
